package com.example.demo.core;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletResponse;

import static com.example.demo.core.ProjectConstant.FAIL;
import static com.example.demo.core.ProjectConstant.SUCCESS;

@Slf4j
public class RestBusinessTemplate {

    private static final Logger BIZ_LOG = LoggerFactory.getLogger("bizCoreException");


    /**
     * 通过模板执行业务，这里不需要事务
     * @param callback
     * @return
     */
    public static Result execute(Callback callback){
        return doExecute(callback, null);
    }

    /**
     * 使用默认的事务管理器执行业务
     * @param callback
     * @return
     */
    public static Result transaction(Callback callback){
        TransactionTemplate transactionTemplate = ApplicationContextUtil.getBean(TransactionTemplate.class);
        Assert.notNull(transactionTemplate, "default TransactionTemplate must not be null");
        return doExecute(callback, transactionTemplate);

    }

    /**
     * 使用指定的事务管理器执行业务
     * @param callback
     * @return
     */
    public static Result transaction(Callback callback, TransactionTemplate transactionTemplate) {

        Assert.notNull(transactionTemplate, "param transactionTemplate must not be null");
        return doExecute(callback, transactionTemplate);

    }

    public static Result doExecute(Callback callback, TransactionTemplate transactionTemplate){
        Result result = new Result();
        result.setMessage("");
        try {
            result.setCode(ResultCode.SUCCESS);
            result.setMessage(SUCCESS);

            Object o = null;
            if (transactionTemplate != null){
                o = transactionTemplate.execute(status -> {
                    return callback.doExecute();
                });
            }else {
                o = callback.doExecute();
            }
            result.setData(o);
        } catch (BizCoreException e){
            BIZ_LOG.error("业务异常：code={},message={}", e.getCode(), e.getMessage());

            result.setCode(e.getCode());
            result.setMessage(e.getMessage());

        } catch (Exception e){
            // 这里是系统异常
            log.error("系统异常", e);

            result.setCode(ResultCode.SYSTEM_EXCEPTION);
            result.setMessage(FAIL);
        }
        return result;
    }



    /**
     * 执行回调
     * @param <T>
     */
    public interface Callback<T>{
        public T doExecute();
    }
}
